#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <unistd.h>
#include <pthread.h>
#include "LockGuard.hpp"

using namespace std;

//pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

#define NUM 4

class threadData
{
public:
    threadData(int number/*,pthread_mutex_t *mutex*/)
    {
        threadname = "thread-" + to_string(number);
        //lock=mutex;
    }
public:
    string threadname;
    //pthread_mutex_t *lock;
};

int tickets = 1000;


void *getTickets(void *args)
{
    threadData* td= static_cast<threadData*>(args);
    const char *name = td->threadname.c_str();
    while(true)
    {
        //pthread_mutex_lock(&lock);
        //pthread_mutex_lock(td->lock);
        if(tickets > 0)
        {
            usleep(1000);
            printf("who=%s,get a ticket: %d\n",name,tickets);
            tickets--;
            //pthread_mutex_unlock(&lock);
            // pthread_mutex_unlock(td->lock);
        }
        else
        {
            //pthread_mutex_unlock(&lock);
           // pthread_mutex_unlock(td->lock);
            break;
        }
        usleep(13);
    }
    printf("%s ... quit\n",name);
    return nullptr;
}

// void *getTickets(void *args)
// {
//     threadData *td = static_cast<threadData*>(args);
//     const char *name = td->threadname.c_str();
//     while(true)
//     {
//         {
//         LockGuard lockguard(&lock);
//         if(tickets > 0)
//         {
//             usleep(1000);
//             printf("who=%s,get a ticket: %d\n",name,tickets);
//             tickets--;
//         }
//         else
//             break;
//         }
//         usleep(13);
//     }
//     printf("%s ... quit\n",name);
//     return nullptr;
// }

int main()
{
    //pthread_mutex_init(&lock,nullptr);

    vector<pthread_t> tids;
    vector<threadData*> thread_datas;
    for(int i= 1;i<=NUM;i++)
    {
        pthread_t tid;
        threadData *td = new threadData(i);
        thread_datas.push_back(td);
        pthread_create(&tid,nullptr,getTickets,thread_datas[i-1]);
        tids.push_back(tid);
    }

    for(auto thread : tids)
    {
        pthread_join(thread,nullptr);
    }

    for(auto td : thread_datas)
    {
        delete td;
    }

    //pthread_mutex_destroy(&lock);
    return 0;
}